﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.SqlClient;
using System.Data.Odbc;
using System.Configuration;
using System.Data;
using log4net;

namespace BMS.DataAccess
{
    public enum DataSource
    {
        SqlServer,
        Access
    }

    public class DAO
    {
        private readonly string _connectionStringTypeAccess = "CON_ACCESS";
        private readonly string _connectionStringTypeSqlServer = "CON_SQLSERVER";
        private readonly ILog _log = LogManager.GetLogger(typeof(DataSource));

        
        #region Methods

        public DAO()
        {
        }

        /// <summary>
        /// Consulta la información para el ingreso de un funcionario
        /// </summary>
        /// <param name="enrollNumber">Identificador del funcionario según el dispositivo biométrico</param>
        /// <returns>Tabla con la información del funcionario</returns>
        public DataTable GetFunctionary(string enrollNumber)
        {
            try
            {

                SqlConnection connection = new SqlConnection(ConfigurationManager.ConnectionStrings[_connectionStringTypeSqlServer].ToString());

                SqlCommand command = new SqlCommand(ConfigurationManager.AppSettings["GetFunctionary"], connection);

                command.CommandType = CommandType.StoredProcedure;

                command.Parameters.Add("@ID_BIOMETRIC", SqlDbType.VarChar).Value = enrollNumber;
                
                _log.Debug("Realizando la conexión a la base de datos");

                connection.Open();

                SqlDataAdapter adapter = new SqlDataAdapter(command);

                DataSet dataset = new DataSet();

                adapter.Fill(dataset);

                connection.Close();

                _log.Debug("Realizando el cierre de conexión a la base de datos");


                if (dataset.Tables != null)
                {
                    _log.Debug(string.Format("Se detectó información para el funcionario: {0}", enrollNumber));

                    return dataset.Tables[0];
                }


            }
            catch (Exception exc)
            {
                _log.Error(string.Format("Se presentaron inconvenientes realizando la consulta de los funcionarios. Mensaje del sistema: {0}", exc.ToString()));
            }

            return null;
        }

        /// <summary>
        /// Consulta la información para el ingreso de un funcionario
        /// </summary>
        /// <param name="enrollNumber">Identificador del funcionario según el dispositivo biométrico</param>
        /// <returns>Tabla con la información del funcionario</returns>
        public DataTable GetDataFromTurnFunctionary(string enrollNumber)
        {
            try
            {
                SqlConnection connection = new SqlConnection(ConfigurationManager.ConnectionStrings[_connectionStringTypeSqlServer].ToString());

                SqlCommand command = new SqlCommand(ConfigurationManager.AppSettings["GetTurnFunctionary"], connection);

                command.CommandType = CommandType.StoredProcedure;

                command.Parameters.Add("@ID_BIOMETRIC", SqlDbType.VarChar).Value = enrollNumber;
                
                _log.Debug("Realizando la conexión a la base de datos");

                connection.Open();

                SqlDataAdapter adapter = new SqlDataAdapter(command);

                DataSet dataset = new DataSet();

                adapter.Fill(dataset);

                connection.Close();

                _log.Debug("Realizando el cierre de conexión a la base de datos");

                if (dataset.Tables != null)
                {
                    _log.Debug(string.Format("Se detectó información del turno para el funcionario: {0}", enrollNumber));

                    return dataset.Tables[0];
                }
            }
            catch (Exception exc)
            {
                _log.Error(string.Format("Se presentaron inconvenientes realizando la consulta de los turnos para los funcionarios. Mensaje del sistema: {0}", exc.ToString()));
            }

            return null;
        }

        /// <summary>
        /// Consulta la información para el ingreso de una persona
        /// </summary>
        /// <param name="enrollNumber">Identificador de la persona según el dispositivo biométrico</param>
        /// <returns>Tabla con la información de la persona</returns>
        public DataTable GetDataFromPerson(string enrollNumber)
        {
            try
            {
                SqlConnection myConnection = new SqlConnection(ConfigurationManager.ConnectionStrings[_connectionStringTypeSqlServer].ToString());

                SqlCommand myCommand = new SqlCommand(ConfigurationManager.AppSettings["Execute"], myConnection);

                myCommand.CommandType = CommandType.StoredProcedure;
                myCommand.Parameters.Add("@ID_BIOMETRIC", SqlDbType.VarChar).Value = enrollNumber;
                myCommand.Parameters.Add("@ENTRY_DATE", SqlDbType.DateTime).Value = DateTime.Now;

                _log.Debug("Realizando la conexión a la base de datos");

                myConnection.Open();

                SqlDataAdapter adapter = new SqlDataAdapter(myCommand);

                DataSet dataset = new DataSet();

                adapter.Fill(dataset);

                myConnection.Close();

                _log.Debug("Realizando el cierre de conexión a la base de datos");

                if (dataset.Tables != null && dataset.Tables.Count > 0)
                {
                    _log.Debug("Se detectó información en la tabla de Personas");

                    return dataset.Tables[0];
                }
                else
                {
                    _log.Debug("No se detectó información en la tabla de Personas");
                }
            }
            catch (Exception exc)
            {
                _log.Error(string.Format("Se presentaron inconvenientes realizando la consulta de las personas. Mensaje del sistema: {0}", exc.ToString()));
            }

            return null;
        }

        public bool CreateAuthorization(string enrollNumber, string documentNumberPersonAuthorizing, string namePersonAuthorizing, string chargePersonAuthorizing, string headquarterPersonAuthorizing, string costCenterPersonAuthorizing, string companyPersonAuthorizing, string ipDevice, string message)
        {
            int result = 0;

            try
            {
                SqlConnection myConnection = new SqlConnection(ConfigurationManager.ConnectionStrings[_connectionStringTypeSqlServer].ToString());

                _log.Debug(string.Format("Realizando la creación de la autorización para el usuario: {0}", enrollNumber));

                SqlCommand myCommand = new SqlCommand(ConfigurationManager.AppSettings["CreateAuthorization"], myConnection);
                myCommand.CommandType = CommandType.StoredProcedure;
                myCommand.Parameters.Add("@EMPLOYEE_CODE", SqlDbType.VarChar).Value = enrollNumber;
                myCommand.Parameters.Add("@ID_PERSONAUTHORIZING", SqlDbType.Int).Value = Convert.ToInt32(ConfigurationManager.AppSettings["ID_PersonAuthorizing"]);
                myCommand.Parameters.Add("@DOCUMENT_NUMBER_PERSONAUTHORIZING", SqlDbType.VarChar).Value = documentNumberPersonAuthorizing;
                myCommand.Parameters.Add("@NAME_PERSONAUTHORIZING", SqlDbType.VarChar).Value = namePersonAuthorizing;
                myCommand.Parameters.Add("@CHARGE_PERSONAUTHORIZING", SqlDbType.VarChar).Value = chargePersonAuthorizing;
                myCommand.Parameters.Add("@HEADQUARTER_PERSONAUTHORIZING", SqlDbType.VarChar).Value = headquarterPersonAuthorizing;
                myCommand.Parameters.Add("@COSTCENTER_PERSONAUTHORIZING", SqlDbType.VarChar).Value = costCenterPersonAuthorizing;
                myCommand.Parameters.Add("@COMPANY_PERSONAUTHORIZING", SqlDbType.VarChar).Value = companyPersonAuthorizing;
                myCommand.Parameters.Add("@IP_DEVICE", SqlDbType.VarChar).Value = ipDevice;
                myCommand.Parameters.Add("@REASON_MESSAGE", SqlDbType.VarChar).Value = message;

                _log.Debug("Realizando la conexión a la base de datos");

                myConnection.Open();

                result = myCommand.ExecuteNonQuery();

                myConnection.Close();

                _log.Debug("Realizando el cierre de conexión a la base de datos");
            }
            catch (Exception exc)
            {
                _log.Error(string.Format("Se presentaron inconvenientes realizando la creación de la Autorización. Mensaje del sistema: {0}", exc.ToString()));
            }

            return result == 1 ? true : false;
        }

        /// <summary>
        /// Ingreso a la organización por una autorización de un funcionario
        /// </summary>
        /// <param name="enrollNumber">Identificación del usuario según el lector biométrico</param>
        /// <returns>Información del usuario que desea ingresar</returns>
        public DataTable CanEntryByAuthorization(string enrollNumber)
        {
            DataSet dataset = new DataSet();
            try
            {
                SqlConnection myConnection = new SqlConnection(ConfigurationManager.ConnectionStrings[_connectionStringTypeSqlServer].ToString());

                SqlCommand myCommand = new SqlCommand(ConfigurationManager.AppSettings["CanEntryByAuthorization"], myConnection);
                myCommand.CommandType = CommandType.StoredProcedure;
                myCommand.Parameters.Add("@EMPLOYEE_CODE", SqlDbType.VarChar).Value = enrollNumber;

                _log.Debug("Realizando la conexión a la base de datos");
                myConnection.Open();

                SqlDataAdapter adapter = new SqlDataAdapter(myCommand);
                adapter.Fill(dataset);

                myConnection.Close();

                _log.Debug("Realizando el cierre de conexión a la base de datos");

                if (dataset.Tables != null & dataset.Tables.Count > 0)
                {
                    return dataset.Tables[0];
                }
                else
                {
                    return null;
                }
            }
            catch (Exception exc)
            {
                _log.Error(string.Format("Se presentaron inconvenientes validando si el usuario: {0}, tiene autorizaciones pendientes. Mensaje retornado por el sistema: {1}", enrollNumber, exc.ToString()));
            }

            return null;
        }


        /// <summary>
        /// Registro de ingreso de todo funcionario o persona a la organización
        /// </summary>
        /// <param name="enrollNumber">Identificación del usuario según el lector biométrico</param>
        /// <returns>True si la creación del registro fue satisfactoria</returns>
        public bool CreateAuditRegister(string enrollNumber, string documentNumberPersonAuthorizing, string namePersonAuthorizing, string chargePersonAuthorizing, string headquarterPersonAuthorizing, string costCenterPersonAuthorizing, string companyPersonAuthorizing, string ipDevice)
        {
            int result = 0;

            try
            {
                SqlConnection myConnection = new SqlConnection(ConfigurationManager.ConnectionStrings[_connectionStringTypeSqlServer].ToString());

                SqlCommand myCommand = new SqlCommand(ConfigurationManager.AppSettings["CreateEntryRegister"], myConnection);
                myCommand.CommandType = CommandType.StoredProcedure;
                myCommand.Parameters.Add("@EMPLOYEE_CODE", SqlDbType.VarChar).Value = enrollNumber;
                myCommand.Parameters.Add("@DOCUMENT_NUMBER_PERSONAUTHORIZING", SqlDbType.VarChar).Value = documentNumberPersonAuthorizing;
                myCommand.Parameters.Add("@NAME_PERSONAUTHORIZING", SqlDbType.VarChar).Value = namePersonAuthorizing;
                myCommand.Parameters.Add("@CHARGE_PERSONAUTHORIZING", SqlDbType.VarChar).Value = chargePersonAuthorizing;
                myCommand.Parameters.Add("@HEADQUARTER_PERSONAUTHORIZING", SqlDbType.VarChar).Value = headquarterPersonAuthorizing;
                myCommand.Parameters.Add("@COSTCENTER_PERSONAUTHORIZING", SqlDbType.VarChar).Value = costCenterPersonAuthorizing;
                myCommand.Parameters.Add("@COMPANY_PERSONAUTHORIZING", SqlDbType.VarChar).Value = companyPersonAuthorizing;
                myCommand.Parameters.Add("@IP_DEVICE", SqlDbType.VarChar).Value = ipDevice;
                myCommand.Parameters.Add("@MESSAGE", SqlDbType.VarChar).Value = ConfigurationManager.AppSettings["Message"];

                _log.Debug("Realizando la conexión a la base de datos");

                myConnection.Open();

                result = myCommand.ExecuteNonQuery();

                myConnection.Close();

                _log.Debug("Realizando el cierre de conexión a la base de datos");
            }
            catch (Exception exc)
            {
                _log.Error(string.Format("Se presentaron inconvenientes realizando la creación del registro en la auditoría. Mensaje retornado por el sistema: {0}", exc.ToString()));
            }

            return result == 1 ? true : false;
        }

        #endregion Methods

        public bool CreateDeviceRegister(string ipDevice, string state, string observations)
        {
            int result = 0;

            try
            {
                SqlConnection myConnection = new SqlConnection(ConfigurationManager.ConnectionStrings[_connectionStringTypeSqlServer].ToString());

                SqlCommand myCommand = new SqlCommand(ConfigurationManager.AppSettings["CreateDevice"], myConnection);
                myCommand.CommandType = CommandType.StoredProcedure;
                myCommand.Parameters.Add("@IP_DEVICE", SqlDbType.VarChar).Value = ipDevice;
                myCommand.Parameters.Add("@STATE", SqlDbType.VarChar).Value = state;
                myCommand.Parameters.Add("@OBSERVATIONS", SqlDbType.VarChar).Value = observations;

                _log.Debug("Realizando la conexión a la base de datos");

                myConnection.Open();

                result = myCommand.ExecuteNonQuery();

                myConnection.Close();

                _log.Debug("Realizando el cierre de conexión a la base de datos");
            }
            catch (Exception exc)
            {
                _log.Error(string.Format("Se presentaron inconvenientes realizando la creación del registro en la tabla de dispositivos. Mensaje retornado por el sistema: {0}", exc.ToString()));
            }

            return result == 1 ? true : false;
        }
    }
}
